import React, { useMemo, useState } from 'react';
import {
    Layout,
    UI,
    useThemeColors,
    usePermission,
    PermissionsService,
    ToastService,
    Feedback,            // 新增：引入 Feedback 以使用 Dialog
} from '@gaozh1024/rn-toolkit';
import type { PermissionAlias, NotificationOptions } from '@gaozh1024/rn-toolkit';

const ALL_ALIASES: PermissionAlias[] = [
    'camera',
    'microphone',
    'photo',
    'storage',
    'location',
    'locationWhenInUse',
    'locationAlways',
    'bluetooth',
    'notification',
    'contacts',
    'calendar',
];

export default function PermissionsTestScreen() {
    const colors = useThemeColors();
    const [alias, setAlias] = useState<PermissionAlias>('camera');
    const [openSettingsIfBlocked, setOpenSettingsIfBlocked] = useState<boolean>(true);
    const [notifOpts, setNotifOpts] = useState<NotificationOptions>({
        alert: true,
        sound: true,
        badge: true,
        carPlay: false,
        criticalAlert: false,
        provisional: false,
        providesAppSettings: false,
        announcement: false,
    });

    const { Dialog } = Feedback; // 新增：Dialog 引用

    const {
        status,
        isGranted,
        loading,
        check,
        request,
        ensure,
        openSettings,
    } = usePermission(alias);

    const isNotification = useMemo(() => alias === 'notification', [alias]);

    // 新增：统一的“跳转设置”确认方法
    const confirmOpenSettings = async () => {
        return await Dialog.confirm({
            title: '需要前往设置',
            message: '权限可能被禁止，是否跳转至设置页面？',
            type: 'warning',
            confirmText: '去设置',
            cancelText: '取消',
            cancelable: true,
        });
    };

    const onRequestWithOptions = async () => {
        if (isNotification) {
            await request(notifOpts);
        } else {
            await request();
        }
        // 新增：请求后提示与引导
        await check(); // 同步最新状态
        if (status === 'granted') {
            ToastService.show({ message: 'usePermission.request => 已授权' });
        } else if (status === 'blocked' || status === 'denied') {
            ToastService.show({ message: 'usePermission.request => 已拒绝或被禁止' });
            if (openSettingsIfBlocked) {
                const go = await confirmOpenSettings();
                if (go) await openSettings();
            }
        }
    };

    const onEnsureWithOptions = async () => {
        const ok = await ensure({
            openSettingsIfBlocked: false,                // 重要：不自动跳转，改为弹窗确认
            notificationOptions: isNotification ? notifOpts : undefined,
        });
        ToastService.show({ message: ok ? 'usePermission.ensure => OK' : 'usePermission.ensure => Failed' });

        // 新增：失败时根据状态提示是否跳转设置
        if (!ok && openSettingsIfBlocked) {
            await check(); // 同步最新状态
            if (status === 'blocked' || status === 'denied') {
                const go = await confirmOpenSettings();
                if (go) await openSettings();
            }
        }
    };

    const [serviceStatus, setServiceStatus] = useState<string>('-');
    const [serviceIsGranted, setServiceIsGranted] = useState<boolean>(false);

    const updateServiceResult = (res?: { status?: string; isGranted?: boolean }) => {
        setServiceStatus(res?.status ?? '-');
        setServiceIsGranted(!!res?.isGranted);
    };

    const onServiceCheck = async () => {
        const res = await PermissionsService.checkAlias(alias);
        updateServiceResult(res);
    };

    const onServiceRequest = async () => {
        const res = await PermissionsService.requestAlias(alias, isNotification ? notifOpts : undefined);
        updateServiceResult(res);
        // 新增：提示与引导
        if (res.isGranted) {
            ToastService.show({ message: 'service.requestAlias => 已授权' });
        } else {
            ToastService.show({ message: 'service.requestAlias => 已拒绝或被禁止' });
            if (openSettingsIfBlocked && (res.status === 'blocked' || res.status === 'denied')) {
                const go = await confirmOpenSettings();
                if (go) await PermissionsService.openSettings();
            }
        }
    };

    const onServiceEnsure = async () => {
        const ok = await PermissionsService.ensureAlias(alias, {
            openSettingsIfBlocked: false,                // 重要：不自动跳转，改为弹窗确认
        });
        ToastService.show({ message: ok ? 'service.ensureAlias => OK' : 'service.ensureAlias => Failed' });
        // 再读一次状态用于展示
        const res = await PermissionsService.checkAlias(alias);
        updateServiceResult(res);
        // 新增：失败时根据状态提示是否跳转设置
        if (!ok && openSettingsIfBlocked && (res.status === 'blocked' || res.status === 'denied')) {
            const go = await confirmOpenSettings();
            if (go) await PermissionsService.openSettings();
        }
    };


    const quickEnsure = async (name: PermissionAlias) => {
        switch (name) {
            case 'camera': return ToastService.show({ message: (await PermissionsService.ensureCamera({ openSettingsIfBlocked })) ? 'ensureCamera OK' : 'ensureCamera Failed' });
            case 'microphone': return ToastService.show({ message: (await PermissionsService.ensureMicrophone({ openSettingsIfBlocked })) ? 'ensureMicrophone OK' : 'ensureMicrophone Failed' });
            case 'photo': return ToastService.show({ message: (await PermissionsService.ensurePhoto({ openSettingsIfBlocked })) ? 'ensurePhoto OK' : 'ensurePhoto Failed' });
            case 'storage': return ToastService.show({ message: (await PermissionsService.ensureStorage({ openSettingsIfBlocked })) ? 'ensureStorage OK' : 'ensureStorage Failed' });
            case 'locationWhenInUse': return ToastService.show({ message: (await PermissionsService.ensureLocationWhenInUse({ openSettingsIfBlocked })) ? 'ensureLocationWhenInUse OK' : 'ensureLocationWhenInUse Failed' });
            case 'locationAlways': return ToastService.show({ message: (await PermissionsService.ensureLocationAlways({ openSettingsIfBlocked })) ? 'ensureLocationAlways OK' : 'ensureLocationAlways Failed' });
            case 'bluetooth': return ToastService.show({ message: (await PermissionsService.ensureBluetooth({ openSettingsIfBlocked })) ? 'ensureBluetooth OK' : 'ensureBluetooth Failed' });
            case 'notification': return ToastService.show({ message: (await PermissionsService.ensureNotification({ openSettingsIfBlocked })) ? 'ensureNotification OK' : 'ensureNotification Failed' });
            case 'contacts':
            case 'calendar':
            default:
                // 没有便捷方法就走 ensureAlias
                return onServiceEnsure();
        }
    };

    return (
        <Layout.Page
            scrollable
            headerProps={{ title: 'Permissions 测试' }}
        >
            <UI.Text color="text">选择权限 Alias</UI.Text>
            <Layout.Stack gap={8} style={{ flexWrap: 'wrap', marginTop: 8 }}>
                {ALL_ALIASES.map((name) => (
                    <UI.Button
                        key={name}
                        title={name}
                        variant={name === alias ? 'primary' : 'outline'}
                        onPress={() => setAlias(name)}
                        testID={`permissions_alias_${name}_btn`}
                        style={{ marginBottom: 8 }}
                    />
                ))}
            </Layout.Stack>

            <UI.Divider mt={12} mb={12} />

            <UI.Text color="text">usePermission（Hook）</UI.Text>
            <Layout.Card mt={8}>
                <UI.Text testID="use_status_text">status: {String(status)}</UI.Text>
                <UI.Text testID="use_is_granted_text">isGranted: {String(isGranted)}</UI.Text>
                <UI.Text>loading: {String(loading)}</UI.Text>

                <Layout.Stack gap={8} mt={12}>
                    <UI.Button title="check" onPress={check} testID="use_check_btn" />
                    <UI.Button title="request" onPress={onRequestWithOptions} testID="use_request_btn" />
                    <UI.Button title="ensure" onPress={onEnsureWithOptions} testID="use_ensure_btn" />
                    <UI.Button title="openSettings" onPress={openSettings} testID="use_open_settings_btn" />
                </Layout.Stack>
            </Layout.Card>

            <UI.Text color="text" style={{ marginTop: 16 }}>Hook 选项</UI.Text>
            <Layout.Card mt={8}>
                <Layout.Stack align="center" gap={12}>
                    <UI.Text>openSettingsIfBlocked</UI.Text>
                    <UI.Switch
                        value={openSettingsIfBlocked}
                        onValueChange={setOpenSettingsIfBlocked}
                        testID="use_open_settings_if_blocked_switch"
                    />
                </Layout.Stack>

                {isNotification && (
                    <>
                        <UI.Text color="text" style={{ marginTop: 12 }}>NotificationOptions（仅通知权限生效）</UI.Text>
                        <Layout.Stack gap={12} style={{ flexWrap: 'wrap', marginTop: 8 }}>
                            {[
                                { key: 'alert', label: 'alert' },
                                { key: 'sound', label: 'sound' },
                                { key: 'badge', label: 'badge' },
                                { key: 'carPlay', label: 'carPlay' },
                                { key: 'criticalAlert', label: 'criticalAlert' },
                                { key: 'provisional', label: 'provisional' },
                                { key: 'providesAppSettings', label: 'providesAppSettings' },
                                { key: 'announcement', label: 'announcement' },
                            ].map(({ key, label }) => (
                                <Layout.Stack key={key} align="center" gap={8}>
                                    <UI.Text>{label}</UI.Text>
                                    <UI.Switch
                                        value={(notifOpts as any)[key] ?? false}
                                        onValueChange={(v) => setNotifOpts((prev) => ({ ...prev, [key]: v }))}
                                        testID={`notif_${key}_switch`}
                                    />
                                </Layout.Stack>
                            ))}
                        </Layout.Stack>
                    </>
                )}
            </Layout.Card>

            <UI.Divider mt={16} mb={12} />

            <UI.Text color="text">PermissionsService（类）</UI.Text>
            <Layout.Card mt={8}>
                <UI.Text testID="service_status_text">status: {serviceStatus}</UI.Text>
                <UI.Text testID="service_is_granted_text">isGranted: {String(serviceIsGranted)}</UI.Text>

                <Layout.Stack gap={8} mt={12}>
                    <UI.Button title="checkAlias" onPress={onServiceCheck} testID="service_check_btn" />
                    <UI.Button title="requestAlias" onPress={onServiceRequest} testID="service_request_btn" />
                    <UI.Button title="ensureAlias" onPress={onServiceEnsure} testID="service_ensure_btn" />
                    <UI.Button
                        title="openSettings1"
                        onPress={async () => {
                            const go = await confirmOpenSettings();
                            if (go) await PermissionsService.openSettings();
                        }}
                    />
                </Layout.Stack>
            </Layout.Card>

            <UI.Text color="text" style={{ marginTop: 16 }}>便捷 ensureXXX</UI.Text>
            <Layout.Card mt={8}>
                <Layout.Stack gap={8} style={{ flexWrap: 'wrap' }}>
                    {ALL_ALIASES.map((name) => (
                        <UI.Button
                            key={`ensure_${name}`}
                            title={`ensure ${name}`}
                            onPress={() => quickEnsure(name)}
                            testID={`service_ensure_${name}_btn`}
                        />
                    ))}
                </Layout.Stack>
            </Layout.Card>

            <UI.Text color="text" style={{ marginTop: 16 }}>
                注意：请在 iOS Info.plist 与 AndroidManifest.xml 中声明对应权限用途，否则请求会被拒绝或不可用。
            </UI.Text>
        </Layout.Page>
    );
}